package com.gwtrpc.testapp.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.PatternSyntaxException;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.gwtrpc.testapp.client.MyService;

import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.filters.AndFilter;
import org.htmlparser.filters.HasChildFilter;
import org.htmlparser.filters.TagNameFilter;
import org.htmlparser.http.ConnectionManager;
import org.htmlparser.lexer.Page;
import org.htmlparser.util.NodeIterator;
import org.htmlparser.util.NodeList;

import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;


import com.gwtrpc.testapp.shared.EbayDvdInfo;
import com.gwtrpc.testapp.shared.NytBuzz;
import com.gwtrpc.testapp.shared.NytMovie;

@SuppressWarnings("serial")

public class MyServiceImpl extends RemoteServiceServlet implements
	MyService {

		public EbayDvdInfo handleSimpleRequest(String movieTitle){
		
			EbayDvdInfo ebayDvdInfo =  getEbayDvdInfo(movieTitle);
			return ebayDvdInfo;
			
	    }
		
		
		private EbayDvdInfo getEbayDvdInfo(String movieTitle){
		
			
			try{
				String ebayAPI = "http://svcs.ebay.com/services/search/FindingService/v1?";
				String securityAppName = "SECURITY-APPNAME=AliciaDs-4786-429e-aca0-34f139b1e427";
				String opName = "OPERATION-NAME=findItemsAdvanced";			
				String serviceVersion = "SERVICE-VERSION=1.0.0";			
				String responseDataFormat = "RESPONSE-DATA-FORMAT=JSON";
				String restPayload = "REST-PAYLOAD";
				String keywords = "keywords=" + movieTitle;
				String categoryId = "categoryId=617"; //Only look for ["DVD, HD DVD & Blu-ray"]
				String sortOrder = "sortOrder=BestMatch";
				String paginationInput = "paginationInput.entriesPerPage=1";
				String ebayDvdInfoURL = ebayAPI + opName + '&' + serviceVersion + '&' + securityAppName + '&' + responseDataFormat + '&' + restPayload + '&' + keywords + "&" + paginationInput + "&" + categoryId + "&" + sortOrder;
				
				String responseStr=null;	
				String resp = null;
				
				responseStr = getJSONData(ebayDvdInfoURL);		
				JSONArray ebayDvdSearchResponse = new JSONObject(responseStr).getJSONArray("findItemsAdvancedResponse");
				JSONArray ebayDvdSearchResult = ebayDvdSearchResponse.getJSONObject(0).getJSONArray("searchResult");
			
				int itemCount =  Integer.parseInt(ebayDvdSearchResult.getJSONObject(0).getString("@count"));
				
				//Checking if at least 1 item has been returned
				if(itemCount > 0){
					JSONArray ebayDVDItems = ebayDvdSearchResult.getJSONObject(0).getJSONArray("item");
					JSONObject ebayDVDItem = ebayDVDItems.getJSONObject(0); //fetch first item					
					String title = cleanEbayJSONText(ebayDVDItem.getString("title"));
					String galleryURL = cleanEbayJSONText(ebayDVDItem.getString("galleryURL"));
					String viewItemURL = cleanEbayJSONText(ebayDVDItem.getString("viewItemURL"));					
					JSONArray currentPrice = ebayDVDItem.getJSONArray("sellingStatus").getJSONObject(0).getJSONArray("currentPrice");					
					String price =  resp = cleanEbayJSONText(currentPrice.getJSONObject(0).getString("@currencyId")) + " " + cleanEbayJSONText(currentPrice.getJSONObject(0).getString("__value__"));				
					return  new EbayDvdInfo(title, galleryURL, viewItemURL, price);
				} 
			} catch(JSONException je){
				je.printStackTrace();
			} 
			
			return null;
			 
			 
		}
		
		
		private String getJSONData(String apiUrl) {
			StringBuilder json = new StringBuilder();
			try{
							
				URL url = new URL(apiUrl.replaceAll(" ", "%20"));
				URLConnection urlc = url.openConnection();
				
		        BufferedReader in = new BufferedReader(
		                                new InputStreamReader(
		                                		urlc.getInputStream()));
		        String inputLine;
		        while ((inputLine = in.readLine()) != null){ 
		            json.append(inputLine.trim());
		        }
		        in.close();
			}catch(MalformedURLException e){
				e.printStackTrace();
			}catch(IOException e){
				e.printStackTrace();
			}
			return json.toString();
		}
		
		
		private String cleanEbayJSONText(String input){
			
			String cleanInput = input; //start with original input string
			
			try{
				cleanInput = cleanInput.replaceAll("\\\\",""); //remove all backslashes
				cleanInput = cleanInput.replaceAll("\\[\\\"",""); //remove all ["
				cleanInput = cleanInput.replaceAll("\\\"\\]",""); //remove all "]
				
			} catch(PatternSyntaxException pse){
				pse.printStackTrace();				
			}
			
			return cleanInput;
		}
		
		@Override
		public NytBuzz[] getNytBuzz(String search){
			try{
				
				final String apiUrl = "http://api.nytimes.com/svc/search/v1/article";
				String query = "?format=json" + "&query=" + search + "&offset=5&rank=newest&api-key=" ;
				final String apiKey = "fc86debc2f4623ec1c97a25df2115fd5:9:63002980";
				String buzzUrl = apiUrl + query + apiKey;
				System.out.println(buzzUrl);
				String jsonb = getJSONData(buzzUrl);
		        System.out.println(jsonb.charAt(0));
		        System.out.println(jsonb.trim());
				JSONArray NytResult = new JSONObject(jsonb.trim()).getJSONArray("results");
				NytBuzz[] NytArray = new NytBuzz[NytResult.length()];
				System.out.println("Movie Buzz size:" + NytResult.length());
				for(int i=0; i<NytResult.length(); i++){
					JSONObject Buzz = NytResult.getJSONObject(i);
					String title = Buzz.getString("title");
					String url = Buzz.getString("url");
					String description = Buzz.getString("body");
					NytArray[i] = new NytBuzz(description,title,url);
				}
				return NytArray;
				
				
			}catch(JSONException e){
				e.printStackTrace();
			}
			return null;
			
			
		}
		
		@Override
		public NytMovie[] getNytMovie(){
			try{
		        
				final String apiUrl = "http://api.nytimes.com/svc/movies/v2/reviews/dvd-picks.json";
				final String apiKey = "4fa72c328bb7dd8f484af8256d263acf:3:63002980";
				String nytUrl = apiUrl + "?&offset=20&order=by-dvd-release-date" + "&api-key="+ apiKey;
				
				String json = getJSONData(nytUrl);
				
				JSONArray NytMovieResult = new JSONObject(json).getJSONArray("results");
						
				System.out.println("NYT Movie size:" + NytMovieResult.length());
				System.out.println("Using only first 20");
				
				//Trimming result
				int cutoff;
				if(NytMovieResult.length() > 0){
					cutoff = 20;
				} else {
					cutoff = 0;	
				}
				
				NytMovie[] NytMovieArray = new NytMovie [cutoff];
				int finalcount = 0;
				
				for(int i=0; i<cutoff; i++){
				//for(int i=0; i<NytMovieResult.length(); i++){
					JSONObject nytMovie = NytMovieResult.getJSONObject(i);
					String id = nytMovie.getString("nyt_movie_id");
					String title = nytMovie.getString("display_title");
					String description = nytMovie.getString("summary_short");
	                String review = nytMovie.getJSONObject("link").getString("url");               
	                String overview = nytMovie.getJSONArray("related_urls").getJSONObject(0).getString("url");
	                
	                String image = ParserOverview(overview);
	                if(image != "NotFound"){
	                	NytMovieArray[finalcount]= new NytMovie(id,title,image,description,review,overview);
	                	finalcount++;
	                }              
				} 
				
				//Slicing from source array
				NytMovie[] NytMovieArrayFinal = new NytMovie [finalcount];
				for(int j=0;j<finalcount;j++){
					NytMovieArrayFinal[j] = NytMovieArray[j];
				}
				
				return NytMovieArrayFinal;
			}catch(JSONException e){
				e.printStackTrace();
			}
			return null;
		}
		
		
		private String ParserOverview(String overview) {
			int start;
			int end;
			String imageurl=null;
			ConnectionManager manager;
			try{
			        manager=Page.getConnectionManager();
			        Parser parser = null;
			        parser = new Parser(manager.openConnection(overview));
			        
			        NodeFilter filter=new AndFilter(new TagNameFilter("div"),new HasChildFilter(new TagNameFilter("img")));
			        NodeList nodelist=parser.parse(filter);
			        NodeIterator it=nodelist.elements();
			        while(it.hasMoreNodes()){
			        	Node node=(Node)it.nextNode();
			           
			        	if(node.toHtml().contains("runaroundRight")){
			           
			           
			               String parseurl = node.getChildren().elementAt(1).toHtml();
			               start =parseurl.indexOf("src=")+5;
			               end = parseurl.indexOf(".jpg")+4;
			               imageurl=parseurl.substring(start,end);
			               
			               URL url = new URL(imageurl.replaceAll(" ", "%20"));
						   int c = url.openConnection().getContentLength();
						   
						   System.out.println("Content Length:" + c);
						   
						   //File not found in NY Times - Horrible horrible hack, Content length = 292 for File Not Found
						   //if(c == 292){	
						   if(c < 500){
							   //imageurl="http://www.cityofslt.us/cityattorney/not_available_collection.gif";
							   //imageurl="http://www.meanwelldirect.co.uk/public/ranges/images/1225/Image%20Unavailable.jpg";
							   imageurl = "NotFound";
						   }
			           }
			           
			           
			        }        
			   }catch(Exception e){     		        
			        e.printStackTrace();
			   }
			        
			   return(imageurl);
		}
		
}